package HeSuanServer.uitl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @描述:
 * @author: LH
 * @date: 2022/12/7
 */
@Slf4j
public class JwtUtil {
    private static final String KEY="secret";//假设服务端秘钥
    /**
     * 生成 JWT Token
     * */
    public static String createJWTToken(Map<String,String> userMap,Integer time) throws JWTCreationException {
//        String secret=KEY;
        Algorithm algorithm = Algorithm.HMAC256(KEY);
        //jwt 头部信息
        Map<String,Object> map=new HashMap<>();
        map.put("alg","HS256");
        map.put("typ","JWT");

        Date nowDate = new Date();
        Date expireDate = AddDate(nowDate,time*60);//有效时间
        JWTCreator.Builder builder = JWT.create();
        builder.withHeader(map)
//                .withIssuer("SERVICE") //对应 paylaod iss 节点：签发人
//                .withClaim("loginName","fishpro")
//                .withSubject("this is a token demo")//对应 paylaod sub 节点：主题
//                .withAudience("Client")//对应 paylaod aud 节点：受众
                .withIssuedAt(nowDate)//对应 paylaod iat 节点：生效时间
                .withExpiresAt(expireDate); //对应 paylaod  exp 签发人 节点：过期时间
        userMap.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        return  builder.sign(algorithm);
    }


    /**
     * 验证 token
     * */
    public static Map<String,Claim> verifyJWTToken(String token) throws JWTVerificationException {
        Algorithm algorithm=Algorithm.HMAC256(KEY);
        JWTVerifier verifier = JWT.require(algorithm)
//                .withIssuer("SERVICE")
                .build();

        DecodedJWT jwt =verifier.verify(token);
//        String subject=jwt.getSubject();
        Map<String, Claim> claims=jwt.getClaims();
//        List<Claim> list=new ArrayList<>();
//        for (String key : keys) {
//            Claim claim = claims.get(key);
//            list.add(claim);
//            System.out.println("自定义 claim："+claim.asString());
//        }
//        List<String> audience = jwt.getAudience();
//        System.out.println("subject 值："+subject);
//        System.out.println("audience 值："+audience.get(0));
        return claims;
    }

    /**
     * 时间加减法
     * */
    private static Date AddDate(Date date,Integer minute){
        if(null==date)
            date=new Date();
        Calendar cal=new GregorianCalendar();
        cal.setTime(date);
        cal.add(Calendar.SECOND, minute);
        return cal.getTime();
    }
    /**
    * @描述: 测试jwt
    * @参数: [args]
    * @返回值: void
    * @作者: LH
    * @日期: 2022/12/7
    */
    public static void main(String[] args) throws InterruptedException {
        String jwtToken = getString();
        extracted(jwtToken);
//        List<String> list=new ArrayList<>();
//        list.add("id");
//        List<Claim> list1 = new ArrayList<>();
//        try {
//            Map<String, Claim> claimMap = verifyJWTToken(jwtToken);
//        }catch (Exception e){
//            log.info("token错误");
//        }
//        for (Claim claim : list1) {
//            System.out.println(claim.asString());
//        }
    }
    //正确token解析
    private static void extracted(String jwtToken) throws InterruptedException {
        List<String> list=new ArrayList<>();
        list.add("username");
        list.add("password");
        Map<String, Claim> claimMap1 = verifyJWTToken(jwtToken);
        claimMap1.forEach((k,v)->{
            System.out.println(k+"----"+v.asString());
        });
        log.info(new Date().toString());
        Thread.sleep(2*1000);
        try {
            Map<String, Claim> claimMap = verifyJWTToken(jwtToken);
            claimMap.forEach((k,v)->{
                System.out.println(k+"----"+v.asString());
            });
        }catch (Exception e){
            log.info(new Date().toString());
        }
    }

    private static String getString() {
        Map<String,String> map=new HashMap<>();
        map.put("username","Admin");
        map.put("password","Admin");
        String jwtToken = createJWTToken(map,10);
        return jwtToken;
    }
}
